<?php

namespace App\Exports;

use App\Models\Agent;
use App\Models\IndicatorsDailySummary;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;

class AgentTeamListExport extends DefaultValueBinder implements FromArray, WithHeadings, WithMapping, WithCustomValueBinder
{
    use Exportable;

    private $request;

    public function __construct(\Illuminate\Http\Request $request = null)
    {
        $this->request = $request !== null ? $request->all() : [];
    }

    public function headings(): array
    {
        if ((int) ($this->request['type'] ?? 1) === 1) {
            return [
                '代理名称',
                '手机号',
                '个人业绩',
                '团队业绩',
                '当前等级'
            ];
        }

        return [
            '代理名称',
            '个人业绩',
            '团队业绩',
            '当前等级',
            '邀请人',
            '加入时间',
        ];
    }

    public function map($row): array
    {
        if ((int) ($this->request['type'] ?? 1) === 1) {
            return [
                $row['name'],
                $row['phone'],
                (string) (($row['personal_performance'] ?? 0) / 100),
                (string) (($row['team_performance'] ?? 0) / 100),
                Agent::LEVEL_MAP[$row['level']]['text'] ?? ''
            ];
        }

        return [
            $this->removeUncommonWords($this->removeEmoji($row['name'])),
            (string) (($row['personal_performance'] ?? 0) / 100),
            (string) (($row['team_performance'] ?? 0) / 100),
            Agent::LEVEL_MAP[$row['level']]['text'] ?? '',
            $row['direct_inviter']['name'] ?? '',
            $row['created_at'] ?? '',
        ];
    }

    public function array(): array
    {
        return $this->getTeamList(
            $this->request['type'] ?? 1, // 直接邀请
            $this->request['agent_id'] ?? 0,
            $this->request['performance_range_begin'] ?? '',
            $this->request['performance_range_end'] ?? '');
    }

    private function getTeamList($type, $agentId, $performanceRangeBegin = null, $performanceRangeEnd = null)
    {
        return Agent::query()
            ->when($type, function (Builder $builder, $type) use ($agentId) {
                if ((int) $type === 1) {
                    $builder->where('direct_inviter', $agentId);
                } else {
                    $builder
                        ->with('directInviter:id,name')
                        ->where('indirect_inviter', $agentId);
                }
            })
            ->when(
                $performanceRangeBegin && $performanceRangeEnd,
                function (Builder $builder) use ($performanceRangeBegin, $performanceRangeEnd) {
                    $builder
                        ->select([
                            // 这里把 personal_performance 和 team_performance 去掉, 单独另外统计
                            'agents.name', 'agents.phone', 'agents.level', 'agents.direct_inviter', 'agents.created_at'
                        ])
                        ->selectSub(
                        // 个人业绩按日期范围汇总
                            \DB::table('indicators_daily_summary')
                                ->selectRaw('sum(performance_summary)')
                                ->whereBetween('day', [$performanceRangeBegin, $performanceRangeEnd])
                                ->where('type', IndicatorsDailySummary::TYPE_AGENT)
                                ->whereRaw('agent_id = agents.id'),
                            'personal_performance'
                        )
                        ->selectSub(
                        // 团队业绩按日期范围汇总
                            \DB::table('indicators_daily_summary')
                                ->selectRaw('sum(performance_summary)')
                                ->whereBetween('day', [$performanceRangeBegin, $performanceRangeEnd])
                                ->where('type', IndicatorsDailySummary::TYPE_TEAM)
                                ->whereRaw('agent_id = agents.id'),
                            'team_performance'
                        );
                },
                function (Builder $builder) {
                    $builder->select(['agents.name', 'agents.phone', 'agents.level', 'agents.personal_performance', 'agents.team_performance', 'agents.direct_inviter', 'agents.created_at']);
                })
            ->get()
            ->toArray();
    }

    public function bindValue(Cell $cell, $value)
    {
        if (is_numeric($value)) {
            $cell->setValueExplicit($value, DataType::TYPE_STRING);

            return true;
        }

        // else return default behavior
        return parent::bindValue($cell, $value);
    }

    /**
     * 去除生僻字
     * @param $string
     * @return false|string
     */
    public function removeUncommonWords($string)
    {
        return iconv('GBK', 'UTF-8', iconv('UTF-8', 'GBK//IGNORE', $string));
    }

    /**
     * 去除 emoji
     * @param $val
     * @return mixed|string
     */
    public function removeEmoji($val)
    {
        if ($val === '') {
            return '';
        }
        $val = json_encode([$val]);
        $val = preg_replace('#(\\\ud[0-9a-f]{3})#i', '', $val);
        return json_decode($val, true)[0] ?? '';
    }
}
